from openpyxl import Workbook
from openpyxl.styles import Font, Alignment, PatternFill, Border, Side
from io import BytesIO
from typing import List
from app.models.schemas import TestCase, TestCaseResponse
import re


class ExcelService:
    def __init__(self):
        # 测试类型中英文映射
        self.test_type_mapping = {
            'functional': '功能测试',
            'interface': '界面测试',
            'performance': '性能测试',
            'security': '安全测试',
            'compatibility': '兼容性测试',
            'usability': '易用性测试',
            'boundary': '边界测试',
            'exception': '异常测试',
            'integration': '集成测试',
            'regression': '回归测试'
        }

    def format_step(self, index, step_text):
        # 检查步骤是否已经有编号（如"1. 步骤"）
        if re.match(r'^\d+\.\s+', step_text):
            # 如果已有编号，移除它
            step_text = re.sub(r'^\d+\.\s+', '', step_text)
        return f"{index+1}. {step_text}"

    def get_chinese_test_type(self, test_type):
        """将英文测试类型转换为中文"""
        if not test_type:
            return '功能测试'
        return self.test_type_mapping.get(test_type.lower(), test_type)

    def generate_excel(self, response: TestCaseResponse) -> BytesIO:
        """生成Excel文件"""
        wb = Workbook()
        ws = wb.active
        ws.title = "测试用例"

        # 设置样式
        header_font = Font(name='Arial', bold=True, size=12)
        header_fill = PatternFill(
            start_color="DDEBF7", end_color="DDEBF7", fill_type="solid")
        border = Border(
            left=Side(style='thin'),
            right=Side(style='thin'),
            top=Side(style='thin'),
            bottom=Side(style='thin')
        )

        # 添加标题行
        headers = ["测试用例ID", "测试用例标题", "前置条件", "测试步骤", "预期结果", "优先级", "测试类型"]
        for col, header in enumerate(headers, start=1):
            cell = ws.cell(row=1, column=col, value=header)
            cell.font = header_font
            cell.fill = header_fill
            cell.border = border
            cell.alignment = Alignment(
                horizontal='center', vertical='center', wrap_text=True)

        # 添加项目信息
        project_info = []
        if response.project_name:
            project_info.append(f"项目名称: {response.project_name}")
        if response.module_name:
            project_info.append(f"模块名称: {response.module_name}")

        if project_info:
            ws.insert_rows(1, amount=len(project_info) + 1)
            for i, info in enumerate(project_info, start=1):
                cell = ws.cell(row=i, column=1, value=info)
                ws.merge_cells(start_row=i, start_column=1,
                               end_row=i, end_column=len(headers))
                cell.alignment = Alignment(
                    horizontal='left', vertical='center')

            # 添加需求描述
            if hasattr(response, 'requirement') and response.requirement:
                req_row = len(project_info) + 1
                cell = ws.cell(row=req_row, column=1,
                               value=f"需求描述: {response.requirement}")
                ws.merge_cells(start_row=req_row, start_column=1,
                               end_row=req_row, end_column=len(headers))
                cell.alignment = Alignment(
                    horizontal='left', vertical='center', wrap_text=True)

        # 设置列宽
        ws.column_dimensions['A'].width = 15  # ID
        ws.column_dimensions['B'].width = 30  # 标题
        ws.column_dimensions['C'].width = 25  # 前置条件
        ws.column_dimensions['D'].width = 40  # 测试步骤
        ws.column_dimensions['E'].width = 40  # 预期结果
        ws.column_dimensions['F'].width = 10  # 优先级
        ws.column_dimensions['G'].width = 15  # 测试类型

        # 添加测试用例数据
        start_row = len(project_info) + 3 if project_info else 2
        for i, test_case in enumerate(response.test_cases, start=0):
            row = start_row + i

            # 统一转换为字典格式处理
            if isinstance(test_case, dict):
                case_data = test_case
            else:
                # 将对象转换为字典
                if hasattr(test_case, 'model_dump'):
                    case_data = test_case.model_dump()
                elif hasattr(test_case, 'dict'):
                    case_data = test_case.dict()
                else:
                    case_data = test_case.__dict__

            # 提取数据
            case_id = case_data.get(
                'case_id', case_data.get('id', f'TC{i+1:03d}'))
            title = case_data.get('title', f'测试用例 {i+1}')
            preconditions = case_data.get('preconditions', '系统正常运行')
            steps = case_data.get('steps', [])
            expected_results = case_data.get('expected_results', [])
            priority = case_data.get('priority', 'P3')
            test_type = case_data.get(
                'test_type', case_data.get('category', '功能'))

            # 测试用例ID
            cell = ws.cell(row=row, column=1, value=case_id)
            cell.border = border
            cell.alignment = Alignment(horizontal='center', vertical='center')

            # 测试用例标题
            cell = ws.cell(row=row, column=2, value=title)
            cell.border = border
            cell.alignment = Alignment(vertical='center', wrap_text=True)

            # 前置条件
            cell = ws.cell(row=row, column=3, value=preconditions)
            cell.border = border
            cell.alignment = Alignment(vertical='center', wrap_text=True)

            # 测试步骤
            if isinstance(steps, list):
                if steps and isinstance(steps[0], dict):
                    # 如果是字典列表，提取description字段
                    step_texts = []
                    for j, step in enumerate(steps):
                        step_text = step.get('description', f'步骤{j+1}')
                        step_texts.append(self.format_step(j, step_text))
                    steps_text = "\n".join(step_texts)
                else:
                    # 如果是字符串列表
                    steps_text = "\n".join(
                        [self.format_step(j, str(step)) for j, step in enumerate(steps)])
            else:
                steps_text = str(steps) if steps else "无"

            cell = ws.cell(row=row, column=4, value=steps_text)
            cell.border = border
            cell.alignment = Alignment(vertical='top', wrap_text=True)

            # 预期结果 - 从steps中提取expected_result
            if isinstance(steps, list) and steps:
                result_texts = []
                for j, step in enumerate(steps):
                    if isinstance(step, dict):
                        expected_result = step.get(
                            'expected_result', f'预期结果{j+1}')
                        result_texts.append(
                            self.format_step(j, expected_result))
                    else:
                        result_texts.append(self.format_step(j, '操作成功'))
                results_text = "\n".join(result_texts)
            elif isinstance(expected_results, list):
                if expected_results and isinstance(expected_results[0], dict):
                    # 如果是字典列表，提取expected_result字段
                    result_texts = []
                    for j, result in enumerate(expected_results):
                        result_text = result.get(
                            'expected_result', f'预期结果{j+1}')
                        result_texts.append(self.format_step(j, result_text))
                    results_text = "\n".join(result_texts)
                else:
                    # 如果是字符串列表
                    results_text = "\n".join(
                        [self.format_step(j, str(result)) for j, result in enumerate(expected_results)])
            else:
                results_text = str(
                    expected_results) if expected_results else "操作成功"

            cell = ws.cell(row=row, column=5, value=results_text)
            cell.border = border
            cell.alignment = Alignment(vertical='top', wrap_text=True)

            # 优先级
            cell = ws.cell(row=row, column=6, value=priority)
            cell.border = border
            cell.alignment = Alignment(horizontal='center', vertical='center')

            # 测试类型 - 转换为中文
            chinese_test_type = self.get_chinese_test_type(test_type)
            cell = ws.cell(row=row, column=7, value=chinese_test_type)
            cell.border = border
            cell.alignment = Alignment(horizontal='center', vertical='center')

        # 保存到内存中
        output = BytesIO()
        wb.save(output)
        output.seek(0)

        return output
